/*
 * CDocument.h
 *
 *  Created on: Sep 6, 2010
 *      Author: data
 */

#ifndef CDOCUMENT_H_
#define CDOCUMENT_H_

#include "../include/includes.h"
#include "../TokenProcessor/CBasicTokenProcessor.h"
using namespace std;

class CToken;		// incomplete definition
class CTokenList;	// incomplete definition

enum semWikiParts {
	AUTHOR, INFOBOX, SECTION, LINK, CATEGORY
};

enum DocType {
	NEWS, WIKI
};

struct termData {
	size_t termId;
	int termFreq;
};

/**
 * @brief
 */
class CDocument {

protected:
	size_t docId;
	std::string _resource_name;
	size_t _doc_classification_type;
	std::map<std::string, std::string> _doc_feature_map;

	CTokenList* _p_token_list;

	map<string, termData> tokenTermMap;
	map<int, string> semWikiData;
	map<int, vector<size_t> > semWikiTerms;

	string file_contents;
	int no_of_sections;
	int no_of_references;
	vector<size_t> catTermIds;
	size_t JCIntersectCount;
	size_t allTermsCount;
public:
	CDocument(std::string resource_name = "");
	virtual ~CDocument();
    inline CTokenList *get_token_list() const
    {
        return _p_token_list;
    }

    inline size_t get_doc_class_type() const
    {
        return _doc_classification_type;
    }

    inline std::string get_resource_name() const
    {
        return _resource_name;
    }

    inline const std::map<std::string,std::string> & get_feature_map() const
    {
        return _doc_feature_map;
    }

    inline void set_doc_class_type(size_t doc_class_type)
    {
        _doc_classification_type = doc_class_type;
    }

    bool add_token(std::string token);
    bool delete_token(std::string token);
    void process_token_list(CBasicTokenProcessor & token_processor);
    std::string to_string();
    int getNoOfReferences() const;
    int getNoOfSections() const;
    void setNoOfReferences(int noOfReferences);
    void setNoOfSections(int noOfSections);
    vector<size_t> getCatTermIds() const;
    void setCatTermIds(vector<size_t> catTermIds);
    size_t getAllTermsCount() const;
    size_t getJcIntersectCount() const;
    void setAllTermsCount(size_t allTermsCount);
    void setJcIntersectCount(size_t jcIntersectCount);string getFile_contents() const
    {
        return file_contents;
    }

    void setFile_contents(string file_contents)
    {
        this->file_contents = file_contents;
    }

    map<string,termData> getTokenTermMap() const
    {
        return tokenTermMap;
    }

    void setTokenTermMap(map<string,termData> tokenTermMap)
    {
        this->tokenTermMap = tokenTermMap;
    }

    map<int,vector<size_t> > getSemWikiTerms() const
    {
        return semWikiTerms;
    }

    void setSemWikiTerms(map<int,vector<size_t> > semWikiTerms)
    {
        this->semWikiTerms = semWikiTerms;
    }

    map<int,string> getSemWikiData() const
    {
        return semWikiData;
    }

    void setSemWikiData(map<int,string> semWikiData)
    {
        this->semWikiData = semWikiData;
    }

    size_t getDocId() const
    {
        return docId;
    }

    void setDocId(size_t docId)
    {
        this->docId = docId;
    }

};

/**
 * @brief
 */
class CToken {
	std::string _token_raw_string;
	std::string _token_normal_form;
	std::map<std::string, std::string> _token_feature_map;
	CTokenList *_p_child_token_list;
	CTokenList *_p_current_token_list;
	CToken *_p_parent_token;

public:
	/**
	 * @brief
	 * @param p_current_token_list
	 */
	CToken(std::string token = "", CTokenList* p_current_token_list = 0);

public:
	/**
	 * @brief
	 * @return
	 */
	inline std::string get_token_raw_string() const { return _token_raw_string; }
	/**
	 * @brief
	 * @return
	 */
	inline std::string get_token_normal_string() const { return _token_normal_form; }
	/**
	 * @brief
	 * @return
	 */
	inline std::map<std::string, std::string> const & get_feature_map() const { return _token_feature_map; }
	/**
	 * @brief
	 * @return
	 */
	inline CTokenList* get_child_token_list() const { return _p_child_token_list; }
	/**
	 * @brief
	 * @return
	 */
	inline CTokenList* get_current_token_list() const { return _p_current_token_list; }
	/**
	 * @brief
	 * @return
	 */
	inline CToken* get_parent_token() const { return _p_parent_token; }
	/**
	 * @brief
	 * @param normal_string
	 */
	inline void set_token_normal_string(std::string normal_string) { _token_normal_form = normal_string; }
	/**
	 * @brief
	 * @param key
	 * @param value
	 */
	inline void add_feature(std::string key, std::string value) { _token_feature_map[key] = value; }

};

/**
 * @brief
 */
class CTokenList {
	std::list<CToken*>* _p_token_list;
public:
	CTokenList();
	~CTokenList();

	// write down the copy constructors and the assignment operators here
	// CTokenList(CTokenList& a_list);
	// CTokenList& operator=(CTokenList& a_list);

	inline std::list<CToken*>* get_token_list() const { return _p_token_list; }

	/**
	 * @ destroy the token list
	 */
	void destroy_token_list(std::list<CToken*> *head);

	/**
	 * @brief
	 * @param token
	 * @return
	 */
	bool add_token(std::string token);
	/**
	 * @brief
	 * @param token
	 * @return
	 */
	bool delete_token(std::string token);
	/**
	 * @brief
	 * @param p_token
	 * @param splitter_string
	 * @return
	 */
	bool split_token(CToken* p_token, std::string splitter_string);

};


#endif /* CDOCUMENT_H_ */
